package io.bdmc.modules.bss.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import io.bdmc.common.annotation.SysLogger;
import io.bdmc.common.http.HKHttpUtil;
import io.bdmc.common.http.HttpResult;
import io.bdmc.common.http.ZxyHttpUtil;
import io.bdmc.common.nbapi.sdk.api.online.CreateDeviceOpe;
import io.bdmc.common.nbapi.sdk.entity.Device;
import io.bdmc.common.utils.Constant;
import io.bdmc.common.utils.DateUtils;
import io.bdmc.common.utils.ExcelImport;
import io.bdmc.common.utils.MyMap;
import io.bdmc.common.utils.MyPage;
import io.bdmc.common.utils.R;
import io.bdmc.common.validator.ValidatorUtils;
import io.bdmc.common.validator.group.AddGroup;
import io.bdmc.common.validator.group.UpdateGroup;
import io.bdmc.modules.bss.entity.SmkDevice;
import io.bdmc.modules.bss.model.DevParam;
import io.bdmc.modules.bss.model.alarm.GatewayZxy;
import io.bdmc.modules.bss.model.alarm.MessageHKHttp;
import io.bdmc.modules.bss.service.ISmkDeviceService;
import io.bdmc.modules.sys.controller.AbstractController;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author huang lu
 * @since 2019-01-21
 */
@RestController
@RequestMapping("/bss/dev")
public class SmkDeviceController extends AbstractController {

	@Autowired
	private ISmkDeviceService _devSvs;

	// @Autowired
	// private HttpClientUtil _httpSvs;
	
	@Autowired
	private ZxyHttpUtil _zxyUtil;

	@Autowired
	private HKHttpUtil _hkUtil;

	@RequestMapping("/list")
	@RequiresPermissions("bss:dev:list")
	public R list(DevParam params) {
		MyPage<SmkDevice> myPage = new MyPage<SmkDevice>(params.getCurrent(), params.getSize());
		MyPage<SmkDevice> map = _devSvs.mySelectPage(myPage, params);
		return R.ok().putData(MyMap.ok(map.getRecords(), map.getTotal()));
	}

	/**
	 * 新增设备
	 */
	@SysLogger("新增设备")
	@RequestMapping("/save")
	@RequiresPermissions("bss:dev:save")
	public R save(@RequestBody SmkDevice dev) {
		ValidatorUtils.validateEntity(dev, AddGroup.class);
		dev.setCreateBy(getUser().getUsername());
		Boolean b = dev.insert();
		return R.trueOfFalse(b);
	}

	/**
	 * 修改设备
	 */
	@SysLogger("修改设备")
	@RequestMapping("/update")
	@RequiresPermissions("bss:dev:update")
	public R update(@RequestBody SmkDevice dev) {
		ValidatorUtils.validateEntity(dev, UpdateGroup.class);
		Boolean b = dev.updateById();
		return R.trueOfFalse(b);
	}

	/**
	 * 绑定设备
	 */
	@SysLogger("绑定设备")
	@RequestMapping("/bind")
	@RequiresPermissions("bss:dev:bind")
	public R bind(@RequestBody Map<String, String> map) {
		String devs = map.get("devIds");
		List<Long> devIdList = new ArrayList<Long>();
		for (String s : devs.split(",")) {
			devIdList.add(Long.valueOf(s));
		}
		if (devIdList.size() <= 0) {
			return R.error("参数错误。");
		}
		Long shop_id = Long.valueOf(map.get("shopId"));
		Long dept_id = Long.valueOf(map.get("deptId"));
		Integer result = _devSvs.updateBatch(shop_id, dept_id, devIdList.toArray(new Long[devIdList.size()]));
		return R.trueOfFalse(result > 0);
	}

	/**
	 * 解除绑定设备
	 */
	@SysLogger("解除绑定设备")
	@RequestMapping("/unbind")
	@RequiresPermissions("bss:dev:unbind")
	public R unbind(@RequestBody Map<String, String> map) {
		String devs = map.get("devIds");
		List<Long> devIdList = new ArrayList<Long>();
		for (String s : devs.split(",")) {
			devIdList.add(Long.valueOf(s));
		}
		if (devIdList.size() <= 0) {
			return R.error("参数错误。");
		}

		Integer result = _devSvs.unBindDev( devIdList.toArray(new Long[devIdList.size()]));
		return R.trueOfFalse(result > 0);
	}

	/**
	 * 删除设备
	 * @param JSON 
	 */
	@SysLogger("删除设备")
	@RequestMapping("/delete")
	@RequiresPermissions("bss:dev:delete")
	public R delete(@RequestBody long devId, Object JSON) {
		boolean result = false;
		if (devId > 0){
			SmkDevice dev = _devSvs.getById(devId);
			if(dev.getCreateBy().equals("zxyAdmin")){//中消云设备 掉删除接口
				_zxyUtil.deleteGateway(dev.getImei());
			}else if(dev.getCreateBy().equals("HKAdmin")){
				HttpResult re =	_hkUtil.queryDevice(dev.getImei());
				if(re==null){
					return R.error("远程移动iot删除设备出错，本地已删除。");
				}else{
					MessageHKHttp hkData = JSONObject.parseObject(re.getBody(),MessageHKHttp.class);
					String deviceKey = hkData.getData().get("id").toString();
					HttpResult delResult =	_hkUtil.deleteDevice(deviceKey);
					System.out.println(delResult.getBody());
					MessageHKHttp hkDelData = JSONObject.parseObject(delResult.getBody(),MessageHKHttp.class);
					if(!hkDelData.getErrno().equals("0")){
						return R.error("远程移动iot删除设备出错，本地已删除。");
					}
				}
			}
			result = _devSvs.removeById(devId);
		}	
		return R.trueOfFalse(result);
	}

	@RequestMapping(value = "export")
	@RequiresPermissions("bss:dev:export")
	public R downloadAllClassmate(DevParam params) throws IOException {

		MyPage<SmkDevice> myPage = new MyPage<SmkDevice>(1, 50000);
		MyPage<SmkDevice> map = _devSvs.mySelectPage(myPage, params);
		List<SmkDevice> data = map.getRecords();
		if (data.size() == 0) {
			return R.error(-1, "查询数据为空，请更改查询条件！");
		}
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("设备列表");
		String dateString =  DateUtils.formatLocalDateTime(LocalDateTime.now(), DateUtils.FILE_DATE_PATTERN);
		String fileName = "设备列表" + dateString + ".xls";// 设置要导出的文件的名字
		// 新增数据行，并且设置单元格数据
		int rowNum = 1;
		String[] headers = { "序号","设备名称", "设备型号", "imei", "iccid", "运营商","设备状态","所属部门","上级部门", "店铺名称", "客户名称", "客户手机", "安装时间", "店铺地址",
				"安装位置","电池电量","信号强度(dBm)","信噪比(dB)","信号覆盖等级(dB)","污染百分比","RSSI场强值","烟雾浓度" , "状态时间","设备厂商"};
		// headers表示excel表中第一行的表头
		HSSFRow row = sheet.createRow(0);
		// 在excel表中添加表头
		for (int i = 0; i < headers.length; i++) {
			HSSFCell cell = row.createCell(i);
			HSSFRichTextString text = new HSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}

		// 在表中存放查询到的数据放入对应的列
		for (SmkDevice d : data) {
			HSSFRow row1 = sheet.createRow(rowNum);
			row1.createCell(0).setCellValue(rowNum);
			row1.createCell(1).setCellValue(d.getDevName() != null ? d.getDevName() : "");
			row1.createCell(2).setCellValue(d.getDevModel() != null ? d.getDevModel() : "");
			row1.createCell(3).setCellValue(d.getImei() != null ? d.getImei() : "");
			row1.createCell(4).setCellValue(d.getIccid() != null ? d.getIccid() : "");
			row1.createCell(5).setCellValue(d.getOperator() != null ? d.getOperator() : "");
			row1.createCell(6).setCellValue(d.getDevStatus()!=null&&d.getDevStatus() == 1 ? "在线" : "离线");
			row1.createCell(7).setCellValue(d.getDepName() != null ? d.getDepName() : "");
			row1.createCell(8).setCellValue(d.getParentDept() != null ? d.getParentDept() : "");
			row1.createCell(9).setCellValue(d.getShopName() != null ? d.getShopName() : "");
			row1.createCell(10).setCellValue(d.getManagerName() != null ? d.getManagerName() : "");
			row1.createCell(11).setCellValue(d.getManagerMobile() != null ? d.getManagerMobile() : "");
			row1.createCell(12).setCellValue(d.getInstallDate() != null ? DateUtils.formatLocalDateTime(d.getInstallDate(), DateUtils.DATE_TIME_PATTERN)  : "");
			row1.createCell(13).setCellValue(d.getShopAddr() != null ? d.getShopAddr() : "");
			row1.createCell(14).setCellValue(d.getInstallAddr() != null ? d.getInstallAddr() : "");
			row1.createCell(15).setCellValue(d.getBatteryPower() != null ? d.getBatteryPower() : "");
			row1.createCell(16).setCellValue(d.getSignalStrength()!= null ? d.getSignalStrength() : "");
			row1.createCell(17).setCellValue(d.getSignalSnr() != null ? d.getSignalSnr() : "");
			row1.createCell(18).setCellValue(d.getSignalEcl()!= null ? d.getSignalEcl() : "");
			row1.createCell(19).setCellValue(d.getDirtyPercent() != null ? d.getDirtyPercent() : "");
			row1.createCell(20).setCellValue(d.getRssi() != null ? d.getRssi() : "");
			row1.createCell(21).setCellValue(d.getSmokeScope() != null ? d.getSmokeScope() : "");
			row1.createCell(22).setCellValue(d.getUpdateDate() != null ? DateUtils.formatLocalDateTime(d.getUpdateDate(), DateUtils.DATE_TIME_PATTERN)  : "");
			row1.createCell(23).setCellValue(d.getDevManufactory() != null ? d.getDevManufactory() : "");
			rowNum++;
		}
		try {
			File path = new File(Constant.EXPORTPATH);
			if (!path.exists()) {
				path.mkdir();
			}
			File f = new File(path.getAbsolutePath() + "/excel/", fileName);
			if (!f.getParentFile().exists()) {
				f.getParentFile().mkdir();
			}
			FileOutputStream fileOutputStream = new FileOutputStream(f);// 指定路径与名字和格式
			workbook.write(fileOutputStream);// 将数据写出去
			fileOutputStream.close();// 关闭输出流
			return R.ok().putData("/excel/" + fileName);
		} catch (Exception e) {
			e.printStackTrace();
			return R.error(-1, e.getMessage());
		}
	}



	
	@RequestMapping("import")
	@RequiresPermissions("bss:dev:import")
	public R importExcel(@RequestParam("file") MultipartFile file,@RequestParam Integer devType) throws Exception {
		// 根据地址和文件名准确获取用户上传的表格
		// File tempFile = new File(file.getInputStream());
		try {
			// 将MultipartFile转换为File类型
			// file.transferTo(tempFile);
			String fileName = file.getOriginalFilename();
			String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
			InputStream in = file.getInputStream();
			List<Map<String, String>> dataList = ExcelImport.read(in, suffix);
			List<SmkDevice> list = new ArrayList<SmkDevice>();
			List<GatewayZxy> gateList = new ArrayList<>();
			List<Device> iotDevs = new ArrayList<>();
			for (int i = 0; i < dataList.size(); i++) {
				String devNum = dataList.get(i).get("编号").toString();
				if(StringUtils.isEmpty(devNum)){
					continue;
				}
				String devModel = dataList.get(i).get("型号").toString();
				String devName = dataList.get(i).get("设备名称").toString();
				String devManufactory = dataList.get(i).get("设备厂商").toString();
				SmkDevice dev1 = new SmkDevice();

				dev1.setDevKey(devNum);
				dev1.setImei(devNum);
				dev1.setDevName(devName);
				dev1.setDevModel(devModel);
				dev1.setDevManufactory(devManufactory);
				dev1.setDeptId(1L);
				dev1.setCreateDate(LocalDateTime.now());
				list.add(dev1);
				if(devType==1){//中消云
					GatewayZxy gate = new GatewayZxy();
					gate.setGateWayName(devNum);
					gate.setLatitude("22.2733");
					gate.setLongitude("113.5375");
					gateList.add(gate);
					dev1.setCreateBy("zxyAdmin");
				}else if(devType==2){//海康
					dev1.setCreateBy("HKAdmin");
					Device device = new Device(devName, devNum, devNum.substring(9,15));
					iotDevs.add(device);
				}
				
			}
			if(list.size()==0){
				return R.error(-1,"表格IMEI数据为空。");
			}
			Boolean re = _devSvs.saveBatch(list);
			if(re){
				if(devType==1&&gateList.size()>0){//中消云
					boolean insertResult = _zxyUtil.insertGateway(gateList);
					if(!insertResult){
					 return R.error(-1,"已添加到本地数据库，但远程接口调用失败。");
					}
				}else if(devType==2){
					CreateDeviceOpe deviceOpe = new CreateDeviceOpe();
					for (Device iot : iotDevs) {
						String result = deviceOpe.operation(iot, iot.toJsonObject()).toString();
						System.out.println(result);
						logger.info(result);
					}
				}

			}
			return R.trueOfFalse(re);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.toString());
			// tempFile.delete();
			// throw new Exception("批量录入用户失败，请检查表格中的数据是否和数据库中的数据冲突！");
			return R.error(-1,"导入失败，请检查表格中的数据是否已存在");
		}
	}

}
